﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace ZXW.DotNet.Common.Basic.Network.Udp
{
    /// <summary>
    /// 简单异步UDP传输
    /// </summary>
    public class UDPSimple
    {
        #region 字段
        private static int m_DefaultPort = 4567;
        private int m_Port;
        private UdpClient m_UdpClient;
        private bool m_IsRun = false; 
        #endregion

        #region 构造函数
        public UDPSimple()
            : this(m_DefaultPort)
        {

        }

        public UDPSimple(int port)
        {
            this.m_Port = port;
        } 
        #endregion

        #region 公共函数
        public void Start()
        {
            if (!m_IsRun)
            {
                m_UdpClient = new UdpClient(m_Port);
                m_UdpClient.BeginReceive(new AsyncCallback(Fun_ReceiveData), null);
                m_IsRun = true;
            }  
        }

        /// <summary>  
        /// 关闭Udp连接  
        /// </summary>  
        public void Stop()
        {
            if (m_IsRun)
            {
                m_UdpClient.Close();
            }
        }  

        /// <summary>  
        /// 发送数据  
        /// </summary>  
        /// <param name="ipep">远程主机地址</param>  
        /// <param name="data">欲发送数据</param>  
        public void Send(IPEndPoint ipep, byte[] data)
        {
            if (m_IsRun)
            {
                if (data.Length > 0)
                    m_UdpClient.Send(data, data.Length, ipep);
            }
        }
        #endregion

        #region 私有方法
        /// <summary>  
        /// 接收数据委托  
        /// </summary>  
        /// <param name="ar"></param>  
        private void Fun_ReceiveData(IAsyncResult ar)
        {

            IPEndPoint ipep = (IPEndPoint)ar.AsyncState;
            byte[] data = m_UdpClient.EndReceive(ar, ref ipep);
            if (data.Length != 0)
                this.OnDataReceive(new UDPSimpleEventArgs(ipep, data));
            //继续从远程主机接收数据报  
            m_UdpClient.BeginReceive(new AsyncCallback(Fun_ReceiveData), null);
        }
        #endregion

        #region 事件
        /// <summary>
        /// UDP数据到达事件
        /// </summary>
        public event EventHandler<UDPSimpleEventArgs> DataReveived;
        #endregion

        #region 受保护函数
        protected virtual void OnDataReceive(UDPSimpleEventArgs e)
        {
            if (this.DataReveived != null)
                this.DataReveived(this, e);
        } 
        #endregion

        #region 属性
        public int Port
        {
            get { return m_Port; }
            set
            {
                if (!m_IsRun)
                    m_Port = value;
                else
                {
                    this.Stop();
                    m_Port = value;
                    this.Start();
                }
            }
        }
        #endregion
    }
}
